using System;
using BSpec.Specification;
using BSpec.Specs;
using NUnit.Framework;

namespace behaviour_specs
{
    namespace with_scenario_of
    {
        public abstract class creating_a_behaviour_from_a_test_fixture_type : SpecificationBase<Behaviour>
        {
            protected Type test_fixture_type;

            protected override void setup_scenario()
            {
            }

            protected override Behaviour create_subject()
            {
                return Behaviour.Create(test_fixture_type);
            }
        }

        public abstract class adding_observations_to_a_behaviour
            : creating_a_behaviour_from_a_test_fixture_type
        {
            [Test]
            public void should_add_inherited_observations_to_the_behaviour()
            {
                the_subject.Observations.should_contain(observation =>
                    observation.Name == "Should add inherited observations to the behaviour");
            }
        }
    }

    namespace given_a_type_that_contains_a_test_fixture
    {
        [TestFixture]
        public class when_creating_a_behaviour : with_scenario_of.creating_a_behaviour_from_a_test_fixture_type
        {
            protected override void setup_scenario()
            {
                test_fixture_type = this.GetType();
            }

            protected override void execute_scenario()
            {
                with_scenario_result(() => the_subject);
            }

            [Test]
            public void should_be_named_for_the_test_fixture_behaviour()
            {
                the_scenario_result<Behaviour>().Name.should_equal("When creating a behaviour");
            }
        }
    }

    namespace given_a_type_that_does_not_contain_a_behaviour
    {
        [TestFixture]
        public class when_creating_a_behaviour : with_scenario_of.creating_a_behaviour_from_a_test_fixture_type
        {
            protected override void setup_scenario()
            {
                test_fixture_type = typeof(string);
            }

            protected override void execute_scenario()
            {
                with_scenario_result(() => the_subject);
            }

            [Test]
            public void should_return_a_null_behaviour()
            {
                the_scenario_result<Behaviour>().should_be_instance_of<NullBehaviour>();
            }
        }
    }

    namespace given_a_behaviour
    {
        [TestFixture]
        public class when_adding_observations : with_scenario_of.adding_observations_to_a_behaviour
        {
            protected override void setup_scenario()
            {
                test_fixture_type = this.GetType();
            }

            protected override void execute_scenario()
            {
                the_subject.AddObservationsFor(test_fixture_type);
            }

            [Test]
            public void should_add_observations_to_the_behaviour()
            {
                the_subject.Observations.should_not_be_empty();
            }
        }
    }
}